/**
 * @file:     net.c
 * @Author:   ChenBlue
 * @email:    ChenBlue952@qq.com
 * @data:     Tue Jan 31 02:18:57 2023
 * @brief:
 */

#include <linux/netdevice.h>

struct net_device* net;
const char mac[] = "12:34:56:78:90:ab";

int vnet_open(struct net_device* dev)
{
	printk("[%s][%d] \n", __func__, __LINE__);
	/* 打开网络设备 一般会做如下动作
	·使能网络外设时钟。
	·申请网络所使用的环形缓冲区。
	·初始化 MAC 外设。
	·绑定接口对应的 PHY 。
	·如果使用 NAPI 的话要使能 NAPI 模块，通过 napi_enable 函数来使能。
	·开启 PHY 。
	·调用 netif_tx_start_all_queues 来使能传输队列，也可能调用 netif_start_queue 函数。
	*/
	return 0;
}

int vnet_stop(struct net_device* dev)
{
	printk("[%s][%d]\n", __func__, __LINE__);
	return 0;
}

// 网络设备操作集
const struct net_device_ops vnetdev_ops = {
	.ndo_open = vnet_open, // ifconfig up
	.ndo_stop = vnet_stop, // ifconfig down
	//.ndo_start_xmit = wifi_mac_hardstart, // TCP/IP TX
	// netif_rx(skb);
};
/*
 * 网络设备初始化。给结构体赋值
 **/
void vnet_setup(struct net_device* vnet)
{
	vnet->netdev_ops = &vnetdev_ops;
	vnet->mtu = 1500; // 最大的传输单元

	strncpy(vnet->dev_addr, mac, 17); // 硬件MAC地址。目前还不清楚为啥不会显示在ifconfig里面
}

static int __init net_init(void)
{
	printk("[%s][%d]\n", __func__, __LINE__);
	net = alloc_netdev(0, "wlan%d", NET_NAME_USER, vnet_setup); // 申请一个网络设备
	if (!net) {
		printk("[%s][%d] alloc_netdev fail\n", __func__, __LINE__);
	}

	register_netdev(net); // 注册网络设备
	return 0;
}

static void __exit net_exit(void)
{
	printk("[%s][%d]\n", __func__, __LINE__);
	unregister_netdev(net);
	free_netdev(net);
}
module_init(net_init);
module_exit(net_exit);

/* 描述驱动程序的一些信息，不是必须的 */
MODULE_AUTHOR("ChenBlue");
MODULE_VERSION("0.1.0");
MODULE_DESCRIPTION("YCKJ net Driver");
MODULE_LICENSE("GPL");
